package com.xyht.sca_s.student_manage_system.modules.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.modules.user.entity.*;
import com.xyht.sca_s.student_manage_system.modules.user.entity.req.SmsApplicationReq;
import com.xyht.sca_s.student_manage_system.modules.user.entity.req.SmsResourceAddReq;
import com.xyht.sca_s.student_manage_system.modules.user.entity.req.SmsResourceReq;
import com.xyht.sca_s.student_manage_system.modules.user.entity.resp.AuthResp;
import com.xyht.sca_s.student_manage_system.modules.user.entity.resp.AuthRoleResp;
import com.xyht.sca_s.student_manage_system.modules.user.entity.resp.ResourceResp;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.*;
import com.xyht.sca_s.student_manage_system.modules.user.service.AuthorizationService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.user.constant.OpenCloseStatusFlag.OPEN_CLOSE_STATUS_OPEN;

@Service
public class AuthorizationServiceImpl implements AuthorizationService {
    @Autowired
    private SmsRoleApplicationRelationMapper smsRoleApplicationRelationMapper;
    @Autowired
    private SmsRoleResourceRelationMapper smsRoleResourceRelationMapper;
    @Autowired
    private SmsResourceMapper smsResourceMapper;
    @Autowired
    private SmsApplicationMapper smsApplicationMapper;
    @Autowired
    private SmsRoleMapper smsRoleMapper;

    @Override
    public ResponseResult getRoleList() {
        List<AuthRoleResp> respList;
        List<SmsRole> list = smsRoleMapper.selectList(new QueryWrapper<>());
        respList = list.stream().map(smsRole -> {
            AuthRoleResp authRoleResp = new AuthRoleResp();
            BeanUtils.copyProperties(smsRole,authRoleResp);
            return authRoleResp;
        }).collect(Collectors.toList());
        return CommonResult.success(respList);
    }

    @Override
    public ResponseResult getAuthList(String roleId ,Integer clientFlag) {
        if (isNullOrEmpty(roleId) || isNullOrEmpty(clientFlag)){
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        SmsRole smsRole = smsRoleMapper.selectById(roleId);
        if (smsRole == null){
            return CommonResult.failed(CommonCodeEnum.ROLE_NOT_EXIST);
        }

        //查询所有界面应用
        List<SmsApplication> appList = smsApplicationMapper.selectList(new QueryWrapper<SmsApplication>()
        .lambda().eq(SmsApplication::getAppClient,clientFlag));
        List<SmsRoleApplicationRelation> openAppList = smsRoleApplicationRelationMapper.selectList(new QueryWrapper<SmsRoleApplicationRelation>()
                .lambda().eq(SmsRoleApplicationRelation::getRoleId,roleId).eq(SmsRoleApplicationRelation::getClientFlag,clientFlag));
        List<String> openAppIDList = openAppList.stream().map(SmsRoleApplicationRelation::getAppId).collect(Collectors.toList());

        List<AuthResp> appRespList = appList.stream().map(smsApplication -> {
            AuthResp authResp = new AuthResp();
            BeanUtils.copyProperties(smsApplication,authResp);
            if (openAppIDList.stream().filter(id -> id.equals(smsApplication.getId().toString())).count() == 1){
                authResp.setIsOpen(OPEN_CLOSE_STATUS_OPEN);
            }
            return authResp;
        }).collect(Collectors.toList());

        //获取界面下权限资源
        for (AuthResp authResp : appRespList){
            List<SmsResource> authResList = smsResourceMapper.selectList(new QueryWrapper<SmsResource>()
                    .lambda().eq(SmsResource::getParentId,authResp.getId()));
            List<SmsRoleResourceRelation> openResList = smsRoleResourceRelationMapper.selectList(new QueryWrapper<SmsRoleResourceRelation>()
                    .lambda()
                    .eq(SmsRoleResourceRelation::getRoleId,roleId)
                    .eq(SmsRoleResourceRelation::getClientFlag,clientFlag)
                    .eq(SmsRoleResourceRelation::getAppId,authResp.getId()));
            List<String> resIDList = openResList.stream().map(SmsRoleResourceRelation::getResourceId).collect(Collectors.toList());

            List<ResourceResp> resRespList = authResList.stream().map(smsResource -> {
                ResourceResp resourceResp = new ResourceResp();
                BeanUtils.copyProperties(smsResource,resourceResp);
                if (resIDList.stream().filter(id-> id.equals(smsResource.getId().toString())).count() == 1){
                    resourceResp.setIsOpen(OPEN_CLOSE_STATUS_OPEN);
                }
                return resourceResp;
            }).collect(Collectors.toList());
            authResp.setResList(resRespList);
        }

        return CommonResult.success(appRespList);
    }

    @Override
    public ResponseResult updateApplication(SmsApplicationReq smsApplicationReq) {
        if (isNullOrEmpty(smsApplicationReq.getAppId()) || isNullOrEmpty(smsApplicationReq.getRoleId())
        || isNullOrEmpty(smsApplicationReq.getClientFlag()) || isNullOrEmpty(smsApplicationReq.getStatus())){
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsApplication smsApplication = smsApplicationMapper.selectById(smsApplicationReq.getAppId());
        if (smsApplication == null){
            return CommonResult.failed(CommonCodeEnum.AUTH_APP_NOT_EXIST);
        }
        SmsRole smsRole = smsRoleMapper.selectById(smsApplicationReq.getRoleId());
        if (smsRole == null){
            return CommonResult.failed(CommonCodeEnum.ROLE_NOT_EXIST);
        }

        //开启界面 导入关系
        if (smsApplicationReq.getStatus() == OPEN_CLOSE_STATUS_OPEN){
            SmsRoleApplicationRelation applicationRelation = new SmsRoleApplicationRelation();
            BeanUtils.copyProperties(smsApplicationReq,applicationRelation);

            smsRoleApplicationRelationMapper.insert(applicationRelation);
        }else {
            //关闭界面 删除关系
            QueryWrapper<SmsRoleApplicationRelation> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SmsRoleApplicationRelation::getAppId,smsApplicationReq.getAppId())
                    .eq(SmsRoleApplicationRelation::getRoleId,smsApplicationReq.getRoleId())
                    .eq(SmsRoleApplicationRelation::getClientFlag,smsApplicationReq.getClientFlag());

            smsRoleApplicationRelationMapper.delete(queryWrapper);
        }
        return CommonResult.success();
    }

    @Override
    public ResponseResult updateResourceAuthorization(SmsResourceReq smsResourceReq) {
        if (isNullOrEmpty(smsResourceReq.getResourceId()) || isNullOrEmpty(smsResourceReq.getRoleId())
                || isNullOrEmpty(smsResourceReq.getClientFlag()) || isNullOrEmpty(smsResourceReq.getStatus())){
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsResource smsResource = smsResourceMapper.selectById(smsResourceReq.getResourceId());
        if (smsResource == null){
            return CommonResult.failed(CommonCodeEnum.AUTH_RES_NOT_EXIST);
        }
        SmsRole smsRole = smsRoleMapper.selectById(smsResourceReq.getRoleId());
        if (smsRole == null){
            return CommonResult.failed(CommonCodeEnum.ROLE_NOT_EXIST);
        }

        //开启界面 导入关系
        if (smsResourceReq.getStatus() == OPEN_CLOSE_STATUS_OPEN){
            SmsRoleResourceRelation resourceRelation = new SmsRoleResourceRelation();
            BeanUtils.copyProperties(smsResourceReq,resourceRelation);

            smsRoleResourceRelationMapper.insert(resourceRelation);
        }else {
            //关闭界面 删除关系
            QueryWrapper<SmsRoleResourceRelation> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SmsRoleResourceRelation::getResourceId,smsResourceReq.getResourceId())
                    .eq(SmsRoleResourceRelation::getRoleId,smsResourceReq.getRoleId())
                    .eq(SmsRoleResourceRelation::getClientFlag,smsResourceReq.getClientFlag());

            smsRoleResourceRelationMapper.delete(queryWrapper);
        }
        return CommonResult.success();
    }

    @Override
    public ResponseResult addResource(SmsResourceAddReq smsResourceAddReq) {
        if (isNullOrEmpty(smsResourceAddReq.getName()) || isNullOrEmpty(smsResourceAddReq.getParentId())
        || isNullOrEmpty(smsResourceAddReq.getUrl())){
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsResource smsResource = new SmsResource();
        BeanUtils.copyProperties(smsResourceAddReq,smsResource);
        smsResourceMapper.insert(smsResource);
        return CommonResult.success();
    }
}
